package com.example.pengxiangedupay.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.example.pengxiangedupay.common.constant.OrderStatus;
import com.example.pengxiangedupay.entity.OrderInfoEntity;
import com.example.pengxiangedupay.service.AlipayService;
import com.example.pengxiangedupay.service.FeeStuPaidService;
import com.example.pengxiangedupay.service.OrderInfoService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

@Service
@Slf4j
public class AlipayServiceImpl implements AlipayService {

    @Value("${server.ip}")
    String address;
    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private AlipayClient alipayClient;
    @Autowired
    private FeeStuPaidService feeStuPaidService;

    private final ReentrantLock lock = new ReentrantLock();
    @Override
    @Transactional
    public String tradeCreate(Long productId,String feePayJson) {

        try {
            JSONObject jsonObject = JSON.parseObject(feePayJson);
            BigDecimal total = new BigDecimal(((Integer)jsonObject.get("费用合计")).toString());
            //生成订单

            OrderInfoEntity orderInfo = orderInfoService.createOrderByProductId(productId,total);
            //调用支付宝接口
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            System.out.println(address);
//            request.setReturnUrl("http://111.229.11.46:7777/payInfo?payStatus=1");
            request.setReturnUrl("http://" + address +":7777/payInfo?payStatus=1");
//            request.setNotifyUrl("http://111.229.11.46:7778/app/trade/notify");
            request.setNotifyUrl("http://" + address + ":7778/app/trade/notify");
            System.out.println(request.getNotifyUrl());
            //组装方法的请求参数
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no",orderInfo.getOrderNo());
            //设置缴纳总金额
            bizContent.put("total_amount",total);
            bizContent.put("subject",orderInfo.getTitle());
            bizContent.put("product_code","FAST_INSTANT_TRADE_PAY");

            HashMap<String,Object> map = new HashMap<>();
            map.put("id",productId);
            map.put("fee_json",feePayJson);
            String jsonString = JSON.toJSONString(map, SerializerFeature.UseSingleQuotes);
            bizContent.put("body",jsonString);
            //自定义参数
//            HashMap<String,Object> map = new HashMap<>();
//            map.put("id",productId);
//            map.put("fee_json",feePayJson);
//            String jsonString = JSON.toJSONString(map, SerializerFeature.UseSingleQuotes);
//            String idAndFee = URLEncoder.encode(jsonString,"UTF-8");
//            log.info(idAndFee);
//            bizContent.put("passback_params",idAndFee);

            log.info(bizContent.toString());
            request.setBizContent(bizContent.toString());
            AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
            if(response.isSuccess()){
                log.info("调用成功，===》返回结果" + response.getBody());
                return response.getBody();
            }else{
                log.info(response.getCode() + "调用失败，===》返回结果" + response.getBody());
                throw new RuntimeException("创建支付交易失败");
            }
        } catch (AlipayApiException e) {
            throw new RuntimeException("创建支付交易失败",e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean processOrder(Map<String, String> params) {

        log.info("处理订单");

        //获取订单号
        String orderNo = params.get("out_trade_no");

        /*在对业务数据进行状态检查和处理之前，
        要采用数据锁进行并发控制，
        以避免函数重入造成的数据混乱*/
        //尝试获取锁：
        // 成功获取则立即返回true，获取失败则立即返回false。不必一直等待锁的释放
        if(lock.tryLock()) {
            try {

                //处理重复通知
                //接口调用的幂等性：无论接口被调用多少次，以下业务执行一次
                String orderStatus = orderInfoService.getOrderStatus(orderNo);
                if (!OrderStatus.NOTPAY.getType().equals(orderStatus)) {
                    return false;
                }
                //更新数据库
                //学费条目
                Long feeId = Long.valueOf(params.get("feeId"));
                JSONObject feePayItems = JSON.parseObject(params.get("feePayJson"));
                boolean flag = feeStuPaidService.updatePay(feeId, feePayItems);
                if(!flag){
                    return false;
                }
                //更新订单状态
                orderInfoService.updateStatusByOrderNo(orderNo, OrderStatus.SUCCESS);
                //更新学费状态

                //记录支付日志
//                paymentInfoService.createPaymentInfoForAliPay(params);

            } finally {
                //要主动释放锁
                lock.unlock();
            }
        }
        return true;

    }
}
